/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_INTERNAL_H
#define IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_INTERNAL_H

#include "imageknife.h"
#include "imageknife_dispatcher.h"
#include "imageknife_node_internal.h"
#include "file_type_util.h"

namespace ImageKnifeC {

class ImageKnifeInternal : public ImageKnife {
public:
    FileTypeUtil fileTypeUtil;

    static ImageKnifeInternal& GetInstance();

    void InitImageKnifeArkTs(napi_env env, napi_value &exports) override;
    void SetRootNode(std::string id, ArkUI_NodeContentHandle handle, std::shared_ptr<ImageKnifeNode> node);

    void Execute(std::shared_ptr<ImageKnifeRequest> request);

    void CancelRequest(std::shared_ptr<ImageKnifeRequest> request) override;

    std::shared_ptr<ImageKnifeLoader> GetDefaultImageKnifeLoader() const;

    void SetDefaultImageKnifeLoader(std::shared_ptr<ImageKnifeLoader> imageLoader) override;

    virtual std::shared_future<std::string> InitFileCacheAsync(std::string cachePath, size_t size, size_t memory,
                                                               std::string path) override ;

    void InitFileCache(std::string cachePath = "", size_t size = 256,
                       size_t memory = 256 * 1024 * 1024, std::string path = "ImageKnife") override;

    void SetCacheKeyGenerator(CacheKeyGenerator *keyPtr) override;

    CacheKeyGenerator *GetCacheKeyGenerator() const override;

    std::shared_ptr<ImageKnifeRequest> Preload(std::shared_ptr<ImageKnifeOption> imageKnifeOption) override;

    void SetMaxRequests(int concurrency) override;

    int64_t GetCacheLimitSize(CacheStrategy cacheStrategy) override;

    int64_t GetCurrentCacheNum(CacheStrategy cacheStrategy) override;

    int64_t GetCurrentCacheSize(CacheStrategy cacheStrategy) override;
    void DisposeRootNode(std::string id);

    std::shared_ptr<ImageKnifeNodeInternal> GetImageNode(std::string id);
    
    bool RemoveFileCache(std::string &url);
    bool RemoveFileCache(std::shared_ptr<ImageKnifeOption> option);
    bool RemoveAllFileCache(void);
    std::shared_future<bool> RemoveFileAsync(std::string &url) override ;
    std::shared_future<bool> RemoveFileAsync(std::shared_ptr<ImageKnifeOption> option) override;
    std::shared_future<bool> RemoveAllFileAsync(void) override; 

    void RemoveAllMemoryCache() override;
    bool RemoveMemoryCache(std::string url) override;
    bool RemoveMemoryCache(std::shared_ptr<ImageKnifeOption> imageKnifeOption) override;
private:
    typedef struct {
        std::shared_ptr<ImageKnifeNodeInternal> imageNode;
        ArkUI_NodeContentHandle rootNode;
    } contentHandle;

    std::unordered_map<std::string, contentHandle> contentHandleMap_;

    std::shared_ptr<ImageKnifeDispatcher> dispatcher = std::make_shared<ImageKnifeDispatcher>();

    std::shared_ptr<ImageKnifeLoader> imageLoader_ = nullptr;
    CacheKeyGenerator *keyPtr_ = nullptr;

    ImageKnifeInternal() = default;
    ImageKnifeInternal(const ImageKnifeInternal&) = delete;
    ImageKnifeInternal &operator = (const ImageKnifeInternal&) = delete;
    friend ImageKnife &ImageKnife::GetInstance();

    ~ImageKnifeInternal() override
    {
        if (keyPtr_ != nullptr) {
            delete keyPtr_;
            keyPtr_ = nullptr;
        }
    }
};

} // end of namespace

#endif // IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_INTERNAL_H
